#include "dts.h"


int __init dts_init(void)
{
	uint32_t i;
	struct device_node *dn;
	struct property *pp;
	const char *str;
	uint32_t reg[2];
	struct resource r;
	struct of_phandle_args phandle_args;
	// struct of_device_id matches[] = [] = {
	// 	{ .compatible = "atkalpha-test-node" },
	// 	{ /* Sentinel */ }
	// };

	// //通过设备树匹配表查找设备树匹配表
	// dn = of_find_matching_node_and_match(NULL, matches, NULL)
	// //通过节点名称查找设备树节点
	// dn = of_find_node_by_name(NULL, "dts_test_node");
	//通过compatible属性查找设备树节点
	dn = of_find_compatible_node (NULL, NULL, "atkalpha-test-node");
	if(dn == NULL)
	{
		printk("no find device node\r\n");
		return -EIO;
	}

	//获取#address-cells 属性的值
	printk("#address-cells = %d\r\n", of_n_addr_cells(dn));
	//获取#size-cells 属性的值
	printk("#size-cells = %d\r\n", of_n_size_cells(dn));

	//查找compatible属性
	pp = of_find_property(dn, "compatible", NULL);
	if(pp)
	{
		printk("compatible name = %s\r\n", pp->name);
		printk("compatible length = %d\r\n", pp->length);
		printk("compatible value = %s\r\n", (char*)pp->value);
	}

	//获取属性中字符串的值
	if(of_property_read_string(dn, "status", &str) == 0)
		printk("status = %s\r\n", str);

	//获取元素个数
	printk("reg elems size = %d\r\n", of_property_count_elems_of_size(dn, "reg", sizeof(uint32_t)));

	//获取属性中的第0个u32数据
	if(of_property_read_u32_index(dn, "reg", 0, reg) == 0)
		printk("reg[0] = 0x%x\r\n", reg[0]);

	//获取属性中的u32数组
	if(of_property_read_u32_array(dn, "reg", reg, 2) == 0)
		printk("reg[0] = 0x%x, reg[1] = 0x%x\r\n", reg[0], reg[1]);
	
	//将reg属性转换为resource结构体类型
	if(of_address_to_resource(dn, 0, &r) == 0)
		printk("start = 0x%x, size = 0x%x\r\n", r.start, resource_size(&r));
	
	//获取quote属性所引用的节点
	//args对应引用节点中的#args-cells属性，表示引用节点可传入的参数个数
	if(of_parse_phandle_with_args_map(dn, "test-quote", "args", 0, &phandle_args) == 0)
	{
		if(of_property_read_string(phandle_args.np, "compatible", &str) == 0)
			printk("quote compatible = %s\r\n", str);
		printk("args_count = %d\r\n", phandle_args.args_count);
		for(i=0; i<phandle_args.args_count; i++)
			printk("args[%d]= %d\r\n", i, phandle_args.args[i]);
	}
	if(of_parse_phandle_with_args_map(dn, "test-quote", "args", 1, &phandle_args) == 0)
	{
		if(of_property_read_string(phandle_args.np, "compatible", &str) == 0)
			printk("quote compatible = %s\r\n", str);
		printk("args_count = %d\r\n", phandle_args.args_count);
		for(i=0; i<phandle_args.args_count; i++)
			printk("args[%d]= %d\r\n", i, phandle_args.args[i]);
	}

	return 0;
}

void __exit dts_exit(void)
{

}

module_init(dts_init);
module_exit(dts_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("lf");
MODULE_ALIAS("dts_test");
MODULE_DESCRIPTION("dts test");

